<?php namespace App\Services;

use League\Flysystem\Exception;
use Requests;
use Requests_Exception;

class YunPian
{
    private $apiKey = '';
    private $company = '';
    private $baseUrl = 'http://yunpian.com/v1';
    private $getUserUrl = '/user/get.json';
    private $sendSmsUrl = '/sms/send.json';
    private $sendTplSmsUrl = '/sms/tpl_send.json';

    function __construct()
    {
        $this->company = 'pgzhe';//System::getSiteName();
        $this->apiKey  = 'be826f2f95930ef12d0474de26ab5902';//env('YUN_PIAN_API_KEY');
    }

    public function getUser()
    {
        $result = self::doPost($this->getUserUrl, [
            'apikey' => $this->apiKey,
        ]);
        return $result;
    }

    public function sendSms($sendTo, $content)
    {
        $result = self::doPost($this->sendSmsUrl, [
            'apikey' => $this->apiKey,
            'mobile' => $sendTo,
            'text'   => $content,
        ]);
        return $result;
    }

    public function sendBasicSmsWithCode($sendTo, $code)
    {
        $result = self::doPost($this->sendTplSmsUrl, [
            'apikey'    => $this->apiKey,
            'mobile'    => $sendTo,
            'tpl_id'    => 2,
            'tpl_value' => '#code#=' . $code . '&#company#=' . $this->company,
        ]);
        return $result;
    }

    /**
     * @param $url
     * @param array $param
     * @return mixed
     * @throws YunPianException
     */
    private function doPost($url, array $param)
    {
        $response = null;
        try {

            $response = Requests::post($this->baseUrl . $url, [
                'Accept'       => 'text/plain;charset=utf-8',
                'Content-Type' => 'application/x-www-form-urlencoded;charset=utf-8',
            ], $param);
        } catch (Requests_Exception $ex) {
            throw new YunPianException(YunPianException::RequestsException, ['message' => $ex->getMessage()]);
        }

        if (!$response->success) {
            switch ($response->status_code) {
                default:
                    throw new YunPianException(YunPianException::HttpException);
            }
        }

        $res = json_decode($response->body);
        if (is_null($res))
            throw new YunPianException(YunPianException::NotJson);

        switch ($res->code) {
            case 0:
                return $res;
                break;
            default:
                throw new YunPianException(YunPianException::OutOfService, ['msg' => $res->msg]);
        }
    }
}

class YunPianException extends Exception
{
    const RequestsException = 0x01;
    const HttpException = 0x02;
    const OutOfService = 0x03;
    const NotJson = 0x04;

    public function __construct($code, array $data = [], Exception $previous = null)
    {
        switch ($code) {
            case self::RequestsException:
                $message = trans('exception.yun_pian.requests_exception', []);
                break;
            case self::OutOfService:
            case self::NotJson:
                $message = trans('exception.yun_pian.out_of_service', []) . ' ' . $data['msg'];
                break;
            default:
                $message = trans('general.unknown_exception');
                break;
        }

        parent::__construct($message, $code, $previous);
    }
}
